
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Text;
using System.Xml;

using Swaf;
using Swaf.Gui;

using Swaf.BizObj;
using Swaf.Container;
using Swaf.Security;

namespace Articles.Gui
{
	public class ArticleManagementBizProc : BaseBusinessProcess
	{
		protected bool m_didIncrement = false;
		protected bool m_checkForValidPid = true;
		protected bool m_canChangeDetailsBizRule = true;
		//private IBizObjList m_currentArticleParentTree = null;

		public ArticleManagementBizProc(ActiveBizProc procState)
			:base(procState)
		{
		}

		//protected IBizObjList CurrentArticleParentTree
		//{
		//    get
		//    {
		//        if (m_currentBizObj != null)
		//        {
		//            if (m_currentArticleParentTree == null)
		//            {
		//                IResults rc = App.ruleMgr.execute("getBizObjTreeParents", "Articles", m_currentBizObj.get("id"), "DESC");
		//                m_currentArticleParentTree = rc.CallResults as IBizObjList;

		//            }
		//        }
		//        return m_currentArticleParentTree;
		//    }
		//}

		protected override Privileges CurrentEditPrivilege
		{
			get 
			{
				object idx2 = m_procState.get("id");
				string idx = idx2==null?null:idx2.ToString();
				Privileges priv = Privileges.None;
				bool usingArtPriv = m_currentBizObj != null;
				INameAddressSupport appFuns = (INameAddressSupport)CurrentPrincipal.get("AppFunctions");

				string id = m_currentBizObj == null?idx:m_currentBizObj.get("id").ToString();
				if (id != null)
				{
					if (appFuns.containsField(id))
						priv = (Privileges)appFuns.get(id);
					else if (m_currentBizObj != null)
					{
						if (m_currentBizObj.get("parentId") != null && appFuns.containsField(id = m_currentBizObj.get("parentId").ToString()))
							priv = (Privileges)appFuns.get(id);
						else if (m_currentBizObj.get("rootId") != null && appFuns.containsField(id = m_currentBizObj.get("rootId").ToString()))
							priv = (Privileges)appFuns.get(id);
						else
							priv = CurrentPrincipal.getPrivilege("AppFunctions.ManageArticles");
					}
					else
						priv = CurrentPrincipal.getPrivilege("AppFunctions.ManageArticles");
				}
				else
					priv = CurrentPrincipal.getPrivilege("AppFunctions.ManageArticles");
				return priv; 
			}
		}
		protected override IBizObj createNewBizObj()
		{
			return setupNewBizObj(App.bizObjMgr.create(BizObjTypeName));
		}

		protected override string BizObjTypeName {get{return "Article";}}

		protected virtual IBizObj setupNewBizObj(IBizObj obj)
		{
			object pid = m_procState.get("pid");
			if (CurrentBizObj != null)
				pid = CurrentBizObj.get("parentId");
			if (pid is string)
			{
				IResults rc = App.ruleMgr.execute("getArticleIdFromUniqueTitle", pid);
				pid = rc.CallResults;
			}
			obj.put("parentId", pid);
			obj.put("id", new Swaf.BGuid.Guid());
			obj.put("baseTitle", "New Article");
			obj.put("counts.author.id", CurrentUser.get("id"));
			return obj;
		}

		protected override object convertValueToKeyType(object val)
		{
			Swaf.BGuid.Guid id;

			if (val is Swaf.BGuid.Guid)
				return val;
			if (val!=null && Swaf.BGuid.Guid.TryParse(val.ToString(), out id))
				return id;
			if (val is string)
			{
				IResults rc = App.ruleMgr.execute("getArticleIdFromUniqueTitle", val);
				return rc.CallResults;
			}
			return val;
		}

		protected override void getBizObjList()
		{
			//The test for no pid specified in the state ensures that we dont get the
			//entire tree of article unless that is what is really wanted. To get the
			//entire tree of articles the pid should be an empty string, not null.
			object pid = m_procState.get("pid");
			if (m_checkForValidPid && pid == null)
			{
				m_bizobjs = null;
				base.m_retrievedBizObjList = true;
			}
			else
				base.getBizObjList();
		}
		protected override object[] getBizObjListRuleParameters(object parentId, IBizObj filterSort)
		{
			FlexiMap m = new FlexiMap();
			//The following code allows the bizproc to set its pid='' and get the entire tree of all articles.
			//Without that, the entire tree can never be returned.
			object pid = parentId;
			if ("".Equals(pid))
				pid = null;
			//----------------------------------------------------
			if (pid is string && ((string)pid).Contains("$"))
			{
				string viewName = m_procState.BPC.HostView.ViewName;
				viewName = viewName.Substring(viewName.LastIndexOf('/')+1);
				if (viewName.EndsWith(".aspx"))
					viewName = viewName.Substring(0, viewName.Length - 5);
				pid = ((string)pid).Replace("$PageName$", viewName);
			}

			m.put("parentId", pid);
			object dl = State.State.get("listDetailLevel");
			if (dl is string)
				dl = (DetailLevel)Enum.Parse(typeof(DetailLevel), (string)dl);
			DetailLevel listLevel = (dl is DetailLevel) ? (DetailLevel)dl : DetailLevel.basicDetails;
			m.put("listDetailLevel", listLevel);
			setupGetArticleListMacros(m);
			NameAddressStack s = new NameAddressStack(State.State,m);
			return new object[] { s, filterSort as IBizObj };
		}

		protected virtual void setupGetArticleListMacros(FlexiMap m)
		{
		}

		protected override object[] getDetailsBizRuleParameters(object bizObjKey)
		{
			DetailLevel dl = DetailLevel.fullDetails;
			
			if(State.State.get("displayDetailLevel") is DetailLevel)
				dl = (DetailLevel) State.State.get("displayDetailLevel");
			bool shouldIncrement = !m_didIncrement && (Cmn.IsEmpty(State.State.get("incrementCounts")) || Cmn.IsTrue(State.State.get("incrementCounts")));
			m_didIncrement = true;
			return new object[] { bizObjKey, true, dl, shouldIncrement};
		}

		protected override object[] getDeleteRuleParameters(object bizObjKey)
		{
			return new object[] { bizObjKey, true };
		}

		protected override object[] getUpdateBizRuleParameters(IBizObj bizObj)
		{
			string treeName = State.State.get("objectTreeName") as string;
			if (!Cmn.IsEmpty(treeName))
				bizObj.put("treeName", treeName);
			return new object[] { bizObj };
		}

		public void generateFromYouTube(object infoObj)
		{
			IBizObj info = infoObj as IBizObj;
			IBizObj a = CurrentBizObj;

			if (info != null && a!=null)
			{
				info.put("baseArticleUniqueName", a.get("uniqueTitle").ToString().Length==0 ? a.get("id") : a.get("uniqueTitle"));
				App.ruleMgr.execute("uploadYoutubeArticles", null, null, new object[] { info });
			}
		}

		public void clearPrimaryPicture()
		{
			IResults rc = App.ruleMgr.execute("addPrimaryMedia", "", CurrentBizObj.get("id"));
			getCurrentBizObj();
		}

		public void setPrimaryPicture(object picInfo)
		{
			if (picInfo != null)
			{
				string pictureName = picInfo as string;
				IResults rc = App.ruleMgr.execute("addPrimaryMedia", pictureName, CurrentBizObj.get("id"));
				getCurrentBizObj();
			}
		}
		public void generateFromMedia(object dirInfo)
		{
			if (dirInfo != null)
			{
				Swaf.BGuid.Guid id = CurrentBizObj.get("id") as Swaf.BGuid.Guid;
				if (id == null)
				{
					displayMessageFromBizRuleException("Error-CannotFindArticle", new BaseException("Article Id not found."));
					return;
				}
				string path = ((IBizObj)dirInfo).get("keyName").ToString().Replace(':',System.IO.Path.DirectorySeparatorChar);
				string cacheName = ((IBizObj)dirInfo).get("cacheName").ToString();
				IResults rc = App.ruleMgr.execute("generateArticleFromImages", cacheName, id, path);
				if (rc.ExceptionInfo != null)
					displayMessageFromBizRuleException("Error-GeneratingArticlesFromImages", rc.ExceptionInfo);
			}
		}
		public void switchTranslationMode()
		{
			this.showData(ForceLevel.mustShowGetDetailsDataIfNeeded);
		}

		public void translateAllArticles()
		{
			IResults rc = App.ruleMgr.execute("translateAllCompanyArticles", null);
		}

		public void translateArticle()
		{
			updateBizObj(true);
			IResults rc = App.ruleMgr.execute("translateArticle", CurrentBizObj);
			getCurrentBizObj();
		}

		protected override void getCurrentBizObj()
		{
			if(m_canChangeDetailsBizRule)
				if (!CanEdit && State.State.get("useTemplates") != null && State.State.get("useTemplates").ToString().ToLower().CompareTo("true") == 0)
					base.m_getBizObjDetailsRule = "getArticleTemplate";
				else
					base.m_getBizObjDetailsRule = "getArticleDetail";
			//m_currentArticleParentTree = null;
			base.getCurrentBizObj();
		}

		protected override void setupRuleNames()
		{
			base.m_getBizObjListRule = "getArticles";
			base.m_updateBizObjRule = "updateArticle";
			base.m_deleteBizObjRule = "deleteArticle";
		}
		public override void cancelEdits()
		{
			App.sessionData["TranslationMode"] = false;
			base.cancelEdits();
		}
		protected override void setupActions()
		{
			base.setupActions();
			Actions.addAction(new GenericAction("ClearArticlePicture", (CurrentEditPrivilege > Privileges.Edit), clearPrimaryPicture, this));
			Actions.addAction(new GenericAction("GenerateFromYouTube", true, (CurrentEditPrivilege > Privileges.Edit), this, new ActionParamTrigger(generateFromYouTube), new object[] { }));
			Actions.addAction(new GenericAction("SetArticlePicture", true, (CurrentEditPrivilege > Privileges.Edit), this, new ActionParamTrigger(setPrimaryPicture), new object[] { }));
			Actions.addAction(new GenericAction("GenerateFromMedia", true, (CurrentEditPrivilege > Privileges.Edit), this, new ActionParamTrigger(generateFromMedia), new object[] { }));
			Actions.addAction(new GenericAction("SwitchTranslation", (CurrentEditPrivilege > Privileges.Edit), switchTranslationMode, this));
			Actions.addAction(new GenericAction("TranslateArticle", true, translateArticle, this));
			Actions.addAction(new GenericAction("TranslateAllArticles", true, translateAllArticles, this));
		}
		public override void updateActionState()
		{
			base.updateActionState();
			((GenericAction)Actions["ClearArticlePicture"]).Availability = CanEdit ? ActionAvailability.enabled : ActionAvailability.none;
			((GenericAction)Actions["GenerateFromYouTube"]).Availability = CanEdit ? ActionAvailability.enabled : ActionAvailability.none;
			((GenericAction)Actions["SetArticlePicture"]).Availability = CanEdit ? ActionAvailability.enabled : ActionAvailability.none;
			((GenericAction)Actions["GenerateFromMedia"]).Availability = CanEdit ? ActionAvailability.enabled : ActionAvailability.none;
			((GenericAction)Actions["SwitchTranslation"]).Availability = CanEdit ? ActionAvailability.enabled : ActionAvailability.none;
			((GenericAction)Actions["TranslateArticle"]).Availability = CanEdit ? ActionAvailability.enabled : ActionAvailability.none;
			((GenericAction)Actions["TranslateAllArticles"]).Availability = CanEdit ? ActionAvailability.enabled : ActionAvailability.none;
		}
		public bool TranslationMode
		{
			get
			{
				if(App.sessionData["TranslationMode"]!=null)
					return (bool)App.sessionData["TranslationMode"];
				return false;
			}
		}

	}
}
